# 在任何tkinter导入之前设置环境
import sys
import os
from modules.tkinter_setup import setup_tcltk_environment
setup_tcltk_environment()

import tkinter as tk
from tkinter import ttk, messagebox
from typing import Dict, Callable, Optional, Any

class SettingsManager:
    """属性窗口管理器，负责管理和显示程序的各种设置项"""
    
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        """实现单例模式"""
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self, root=None, config_manager=None, hotkey_update_callback=None):
        """初始化设置管理器
        
        Args:
            root: Tkinter根窗口
            config_manager: 配置管理器实例
            hotkey_update_callback: 热键更新回调函数
        """
        # 防止重复初始化
        if hasattr(self, '_initialized') and self._initialized:
            # 更新参数
            if root is not None:
                self.root = root
            if config_manager is not None:
                self.config = config_manager
            if hotkey_update_callback is not None:
                self.hotkey_update_callback = hotkey_update_callback
            return
        
        self.root = root
        self.config = config_manager
        self.hotkey_update_callback = hotkey_update_callback
        self._settings_window = None
        self._settings_listbox = None
        self._right_frame = None
        self._current_settings_frame = None
        
        # 设置项注册表
        self._settings_registry = {}
        
        # 初始化设置项
        self._initialize_settings()
        
        self._initialized = True
    
    def _initialize_settings(self):
        """初始化默认设置项"""
        # 注册截图设置项
        self.register_setting_item(
            "截图",
            self._create_screenshot_settings,
            priority=10
        )
    
    def register_setting_item(self, name: str, create_func: Callable, priority: int = 50):
        """注册新的设置项
        
        Args:
            name: 设置项名称
            create_func: 创建设置内容框架的函数
            priority: 优先级，数值越小越靠前
        """
        self._settings_registry[name] = {
            'name': name,
            'create_func': create_func,
            'priority': priority,
            'frame': None
        }
    
    def show_settings(self):
        """显示属性设置窗口（单例模式）"""
        # 防止重复打开
        if self._settings_window is not None:
            try:
                self._settings_window.lift()
                self._settings_window.focus_force()
                return
            except Exception:
                self._settings_window = None
        
        if self.root is None:
            messagebox.showerror("错误", "无法创建设置窗口：未提供根窗口")
            return
        
        if self.config is None:
            messagebox.showerror("错误", "无法创建设置窗口：未提供配置管理器")
            return
        
        # 创建设置窗口
        settings_window = tk.Toplevel(self.root)
        settings_window.title("属性")
        settings_window.geometry("500x400")
        
        # 设置为模态窗口
        settings_window.transient(self.root)
        settings_window.grab_set()
        
        # 居中窗口
        self._center_window(settings_window)
        
        # 窗口关闭时清除引用
        def on_closing():
            self._settings_window = None
            settings_window.destroy()
        settings_window.protocol("WM_DELETE_WINDOW", on_closing)
        self._settings_window = settings_window
        
        # 创建主容器
        main_frame = ttk.Frame(settings_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 标题
        title_label = ttk.Label(main_frame, text="属性", font=('Arial', 14, 'bold'))
        title_label.pack(anchor='w', pady=(0, 10))
        
        # 创建分割容器（左右布局）
        content_frame = ttk.Frame(main_frame)
        content_frame.pack(fill=tk.BOTH, expand=True)
        
        # 左侧：列表
        left_frame = ttk.LabelFrame(content_frame, text="设置项", padding=5)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=(0, 5))
        left_frame.config(width=150)
        
        # 设置项列表
        self._settings_listbox = tk.Listbox(left_frame, width=20)
        self._settings_listbox.pack(fill=tk.BOTH, expand=True)
        
        # 按优先级排序设置项并添加到列表
        sorted_settings = sorted(
            self._settings_registry.values(),
            key=lambda x: x['priority']
        )
        
        for i, setting in enumerate(sorted_settings):
            self._settings_listbox.insert(tk.END, setting['name'])
        
        # 默认选中第一个
        if sorted_settings:
            self._settings_listbox.selection_set(0)
        
        # 绑定选择事件
        self._settings_listbox.bind('<<ListboxSelect>>', self._on_setting_selected)
        
        # 右侧：设置内容区域
        self._right_frame = ttk.LabelFrame(content_frame, text="设置内容", padding=10)
        self._right_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 初始显示第一个设置项
        if sorted_settings:
            self._create_and_display_setting(sorted_settings[0]['name'])
        
        # 底部按钮
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(fill=tk.X, pady=(10, 0))
        
        ttk.Button(btn_frame, text="确定", command=on_closing).pack(side=tk.RIGHT, padx=(5, 0))
        ttk.Button(btn_frame, text="取消", command=on_closing).pack(side=tk.RIGHT)
    
    def _create_and_display_setting(self, setting_name: str):
        """创建并显示指定的设置项内容"""
        if setting_name not in self._settings_registry:
            return
        
        setting = self._settings_registry[setting_name]
        
        # 如果设置项框架尚未创建，则创建它
        if setting['frame'] is None:
            setting['frame'] = setting['create_func'](self._right_frame)
        
        # 隐藏当前设置内容
        if self._current_settings_frame is not None:
            self._current_settings_frame.pack_forget()
        
        # 显示新的设置内容
        self._current_settings_frame = setting['frame']
        self._current_settings_frame.pack(fill=tk.BOTH, expand=True)
    
    def _on_setting_selected(self, event=None):
        """设置项选择变化时的处理"""
        if self._settings_listbox is None:
            return
        
        selection = self._settings_listbox.curselection()
        if not selection:
            return
        
        selected_index = selection[0]
        setting_name = self._settings_listbox.get(selected_index)
        
        # 显示对应的设置内容
        self._create_and_display_setting(setting_name)
    
    def _create_screenshot_settings(self, parent):
        """创建截图设置区域"""
        frame = ttk.Frame(parent)
        
        # 截图时隐藏主窗口选项
        self._hide_main_window_var = tk.BooleanVar()
        if self.config:
            self._hide_main_window_var.set(self.config.get_screenshot_hide_main_window())
        
        hide_checkbox = ttk.Checkbutton(
            frame,
            text="截图时隐藏主窗口",
            variable=self._hide_main_window_var,
            command=self._on_hide_main_window_changed
        )
        hide_checkbox.pack(anchor='w', pady=10)
        
        # 开始截图快捷键
        start_hk_frame = ttk.Frame(frame)
        start_hk_frame.pack(fill=tk.X, pady=5)
        ttk.Label(start_hk_frame, text="开始截图:").pack(side=tk.LEFT, padx=(0, 10))
        self._hotkey_start_var = tk.StringVar()
        if self.config:
            self._hotkey_start_var.set(self.config.get_hotkey_start())
        hotkey_entry = ttk.Entry(start_hk_frame, textvariable=self._hotkey_start_var, width=25)
        hotkey_entry.pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(start_hk_frame, text="应用", command=self._apply_hotkey_start).pack(side=tk.LEFT)
        
        # 全屏截图快捷键
        full_hk_frame = ttk.Frame(frame)
        full_hk_frame.pack(fill=tk.X, pady=5)
        ttk.Label(full_hk_frame, text="全屏截图:").pack(side=tk.LEFT, padx=(0, 10))
        self._hotkey_full_var = tk.StringVar()
        if self.config:
            self._hotkey_full_var.set(self.config.get_hotkey_full())
        full_hotkey_entry = ttk.Entry(full_hk_frame, textvariable=self._hotkey_full_var, width=25)
        full_hotkey_entry.pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(full_hk_frame, text="应用", command=self._apply_hotkey_full).pack(side=tk.LEFT)
        
        # 快捷键格式提示
        tip_label = ttk.Label(frame, text="格式: ctrl+alt+i (小写，用+连接)", font=('Arial', 8))
        tip_label.pack(anchor='w', pady=(5, 0))
        
        return frame
    
    def _on_hide_main_window_changed(self):
        """截图时隐藏主窗口选项变化时的处理"""
        if self.config:
            value = self._hide_main_window_var.get()
            self.config.set_screenshot_hide_main_window(value)
            self.config.save()
    

    
    def _apply_hotkey_start(self):
        """应用开始截图快捷键"""
        try:
            if self.config:
                hotkey = self._hotkey_start_var.get().strip()
                if not hotkey:
                    hotkey = 'ctrl+alt+i'
                
                # 保存到配置
                self.config.set_hotkey_start(hotkey)
                self.config.save()
                
                # 通知主窗口重新应用快捷键
                if self.hotkey_update_callback:
                    try:
                        self.hotkey_update_callback()
                        messagebox.showinfo("提示", f"开始截图快捷键已设置为: {hotkey}")
                    except Exception as e:
                        messagebox.showinfo("提示", f"快捷键已保存，将在下次启动时生效: {e}")
                else:
                    messagebox.showinfo("提示", f"开始截图快捷键已设置为: {hotkey}")
        except Exception as e:
            messagebox.showerror("错误", f"设置快捷键失败: {e}")
    
    def _apply_hotkey_full(self):
        """应用全屏截图快捷键"""
        try:
            if self.config:
                hotkey = self._hotkey_full_var.get().strip()
                if not hotkey:
                    hotkey = 'ctrl+alt+shift+i'
                
                # 保存到配置
                self.config.set_hotkey_full(hotkey)
                self.config.save()
                
                # 通知主窗口重新应用快捷键
                if self.hotkey_update_callback:
                    try:
                        self.hotkey_update_callback()
                        messagebox.showinfo("提示", f"全屏截图快捷键已设置为: {hotkey}")
                    except Exception as e:
                        messagebox.showinfo("提示", f"快捷键已保存，将在下次启动时生效: {e}")
                else:
                    messagebox.showinfo("提示", f"全屏截图快捷键已设置为: {hotkey}")
        except Exception as e:
            messagebox.showerror("错误", f"设置快捷键失败: {e}")
    
    def _center_window(self, window):
        """将窗口居中显示"""
        window.update_idletasks()
        width = window.winfo_width()
        height = window.winfo_height()
        x = (window.winfo_screenwidth() // 2) - (width // 2)
        y = (window.winfo_screenheight() // 2) - (height // 2)
        window.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    
    def reset_instance(self):
        """重置实例（用于测试或特殊情况）"""
        SettingsManager._instance = None